import { useState, useRef, useEffect, useCallback } from 'react'
import { UserOutline } from 'antd-mobile-icons'
import Nabar from '../../conpoment/Nabar'
import styles from './ProfessionalFaceRecognition.module.css'
import { Button, Toast, Dialog, Input } from 'antd-mobile'

// 人脸特征点接口
interface FaceLandmark {
  x: number
  y: number
}

// 人脸特征接口
interface FaceFeature {
  id: string
  name: string
  landmarks: FaceLandmark[]
  descriptor: number[]
  timestamp: number
}

// 检测到的人脸接口
interface DetectedFace {
  id: string
  landmarks: FaceLandmark[]
  descriptor: number[]
  confidence: number
  boundingBox: {
    x: number
    y: number
    width: number
    height: number
  }
}

function ProfessionalFaceRecognition() {
  const videoRef = useRef<HTMLVideoElement>(null)
  const canvasRef = useRef<HTMLCanvasElement>(null)
  const [isDetecting, setIsDetecting] = useState(false)
  const [detectedFaces, setDetectedFaces] = useState<DetectedFace[]>([])
  const [stream, setStream] = useState<MediaStream | null>(null)
  const [isLoading, setIsLoading] = useState(false)
  const [faceDatabase, setFaceDatabase] = useState<FaceFeature[]>([])
  const [showRegisterDialog, setShowRegisterDialog] = useState(false)
  const [registerName, setRegisterName] = useState('')
  const [matchedFace, setMatchedFace] = useState<FaceFeature | null>(null)
  const [isVerifying, setIsVerifying] = useState(false)
  const [verificationResult, setVerificationResult] = useState<'success' | 'failed' | null>(null)

  // 初始化人脸数据库（从localStorage加载）
  useEffect(() => {
    const savedDatabase = localStorage.getItem('faceDatabase')
    if (savedDatabase) {
      setFaceDatabase(JSON.parse(savedDatabase))
    }
  }, [])

  // 保存人脸数据库到localStorage
  const saveFaceDatabase = useCallback((database: FaceFeature[]) => {
    localStorage.setItem('faceDatabase', JSON.stringify(database))
    setFaceDatabase(database)
  }, [])

  // 启动摄像头
  const startCamera = async () => {
    try {
      setIsLoading(true)
      const mediaStream = await navigator.mediaDevices.getUserMedia({
        video: {
          width: 640,
          height: 480,
          facingMode: 'user'
        }
      })
      
      setStream(mediaStream)
      
      if (videoRef.current) {
        videoRef.current.srcObject = mediaStream
        videoRef.current.play()
      }
      
      startFaceDetection()
    } catch (error) {
      console.error('摄像头启动失败:', error)
      Toast.show({
        content: '无法访问摄像头，请检查权限设置',
        icon: 'fail'
      })
    } finally {
      setIsLoading(false)
    }
  }

  // 计算两点之间的距离
  const calculateDistance = (p1: FaceLandmark, p2: FaceLandmark): number => {
    return Math.sqrt(Math.pow(p2.x - p1.x, 2) + Math.pow(p2.y - p1.y, 2))
  }

  // 计算人脸特征描述符
  const calculateFaceDescriptor = (landmarks: FaceLandmark[]): number[] => {
    if (landmarks.length < 5) return []
    
    const descriptor: number[] = []
    
    // 计算关键距离比例
    const leftEye = landmarks[0]
    const rightEye = landmarks[1]
    const nose = landmarks[2]
    const leftMouth = landmarks[3]
    const rightMouth = landmarks[4]
    
    // 眼距
    const eyeDistance = calculateDistance(leftEye, rightEye)
    descriptor.push(eyeDistance)
    
    // 鼻梁长度
    const noseLength = calculateDistance(nose, leftEye)
    descriptor.push(noseLength)
    
    // 嘴宽
    const mouthWidth = calculateDistance(leftMouth, rightMouth)
    descriptor.push(mouthWidth)
    
    // 眼鼻比例
    descriptor.push(eyeDistance / noseLength)
    
    // 嘴眼比例
    descriptor.push(mouthWidth / eyeDistance)
    
    // 面部宽度（左右眼到鼻子的距离）
    const leftEyeNose = calculateDistance(leftEye, nose)
    const rightEyeNose = calculateDistance(rightEye, nose)
    descriptor.push(leftEyeNose)
    descriptor.push(rightEyeNose)
    
    // 面部高度（眼到嘴的距离）
    const eyeMouthDistance = calculateDistance(leftEye, leftMouth)
    descriptor.push(eyeMouthDistance)
    
    // 面部角度
    const faceAngle = Math.atan2(rightEye.y - leftEye.y, rightEye.x - leftEye.x)
    descriptor.push(faceAngle)
    
    return descriptor
  }

  // 计算两个描述符的相似度
  const calculateSimilarity = (desc1: number[], desc2: number[]): number => {
    if (desc1.length !== desc2.length) return 0
    
    let sum = 0
    for (let i = 0; i < desc1.length; i++) {
      sum += Math.pow(desc1[i] - desc2[i], 2)
    }
    
    // 使用欧几里得距离的倒数作为相似度
    return 1 / (1 + Math.sqrt(sum))
  }

  // 检测人脸关键点（简化版）
  const detectFaceLandmarks = (imageData: ImageData): FaceLandmark[] => {
    const { data, width, height } = imageData
    const landmarks: FaceLandmark[] = []
    
    // 简化的关键点检测算法
    // 这里使用肤色检测来找到大概的面部区域
    let minX = width, maxX = 0, minY = height, maxY = 0
    let skinPixels = 0
    
    for (let y = 0; y < height; y++) {
      for (let x = 0; x < width; x++) {
        const index = (y * width + x) * 4
        const r = data[index]
        const g = data[index + 1]
        const b = data[index + 2]
        
        // 肤色检测
        if (r > 95 && g > 40 && b > 20 && 
            Math.max(r, g, b) - Math.min(r, g, b) > 15 &&
            Math.abs(r - g) > 15 && r > g && r > b) {
          skinPixels++
          minX = Math.min(minX, x)
          maxX = Math.max(maxX, x)
          minY = Math.min(minY, y)
          maxY = Math.max(maxY, y)
        }
      }
    }
    
    if (skinPixels > 1000) { // 如果检测到足够的肤色像素
      const centerX = (minX + maxX) / 2
      const centerY = (minY + maxY) / 2
      const faceWidth = maxX - minX
      const faceHeight = maxY - minY
      
      // 生成5个关键点（左眼、右眼、鼻子、左嘴角、右嘴角）
      landmarks.push(
        { x: centerX - faceWidth * 0.2, y: centerY - faceHeight * 0.1 }, // 左眼
        { x: centerX + faceWidth * 0.2, y: centerY - faceHeight * 0.1 }, // 右眼
        { x: centerX, y: centerY }, // 鼻子
        { x: centerX - faceWidth * 0.15, y: centerY + faceHeight * 0.2 }, // 左嘴角
        { x: centerX + faceWidth * 0.15, y: centerY + faceHeight * 0.2 }  // 右嘴角
      )
    }
    
    return landmarks
  }

  // 人脸检测主函数
  const detectFaces = useCallback(() => {
    if (!videoRef.current || !canvasRef.current) return

    const video = videoRef.current
    const canvas = canvasRef.current
    const ctx = canvas.getContext('2d')

    if (!ctx || video.readyState !== video.HAVE_ENOUGH_DATA) return

    // 设置canvas尺寸
    canvas.width = video.videoWidth
    canvas.height = video.videoHeight

    // 绘制视频帧
    ctx.drawImage(video, 0, 0, canvas.width, canvas.height)

    // 获取图像数据
    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
    
    // 检测人脸关键点
    const landmarks = detectFaceLandmarks(imageData)
    
    if (landmarks.length >= 5) {
      // 计算人脸描述符
      const descriptor = calculateFaceDescriptor(landmarks)
      
      // 计算边界框
      const xs = landmarks.map(p => p.x)
      const ys = landmarks.map(p => p.y)
      const minX = Math.min(...xs)
      const maxX = Math.max(...xs)
      const minY = Math.min(...ys)
      const maxY = Math.max(...ys)
      
      const detectedFace: DetectedFace = {
        id: `face_${Date.now()}`,
        landmarks,
        descriptor,
        confidence: 0.8,
        boundingBox: {
          x: minX - 20,
          y: minY - 20,
          width: maxX - minX + 40,
          height: maxY - minY + 40
        }
      }
      
      setDetectedFaces([detectedFace])
      
      // 绘制检测结果
      drawFaceDetection(ctx, detectedFace)
      
      // 尝试匹配已知人脸
      matchFace(detectedFace)
    } else {
      setDetectedFaces([])
      ctx.clearRect(0, 0, canvas.width, canvas.height)
    }
  }, [])

  // 绘制人脸检测结果
  const drawFaceDetection = (ctx: CanvasRenderingContext2D, face: DetectedFace) => {
    const { boundingBox, landmarks } = face
    
    // 绘制边界框
    ctx.strokeStyle = '#00ff00'
    ctx.lineWidth = 2
    ctx.strokeRect(boundingBox.x, boundingBox.y, boundingBox.width, boundingBox.height)
    
    // 绘制关键点
    ctx.fillStyle = '#ff0000'
    landmarks.forEach(landmark => {
      ctx.beginPath()
      ctx.arc(landmark.x, landmark.y, 3, 0, 2 * Math.PI)
      ctx.fill()
    })
    
    // 绘制连接线
    ctx.strokeStyle = '#ffff00'
    ctx.lineWidth = 1
    ctx.beginPath()
    ctx.moveTo(landmarks[0].x, landmarks[0].y) // 左眼
    ctx.lineTo(landmarks[1].x, landmarks[1].y) // 右眼
    ctx.moveTo(landmarks[1].x, landmarks[1].y) // 右眼
    ctx.lineTo(landmarks[2].x, landmarks[2].y) // 鼻子
    ctx.moveTo(landmarks[2].x, landmarks[2].y) // 鼻子
    ctx.lineTo(landmarks[0].x, landmarks[0].y) // 左眼
    ctx.stroke()
  }

  // 匹配人脸
  const matchFace = (detectedFace: DetectedFace) => {
    let bestMatch: FaceFeature | null = null
    let bestSimilarity = 0
    
    faceDatabase.forEach(face => {
      const similarity = calculateSimilarity(detectedFace.descriptor, face.descriptor)
      if (similarity > bestSimilarity && similarity > 0.7) { // 相似度阈值
        bestSimilarity = similarity
        bestMatch = face
      }
    })
    
    setMatchedFace(bestMatch)
    
    // 如果在验证模式，处理验证结果
    if (isVerifying) {
      if (bestMatch) {
        setVerificationResult('success')
        Toast.show({
          content: `验证成功！欢迎 ${(bestMatch as FaceFeature).name}`,
          icon: 'success'
        })
        // 3秒后停止验证
        setTimeout(() => {
          stopVerification()
        }, 3000)
      } else {
        setVerificationResult('failed')
        Toast.show({
          content: '验证失败，未找到匹配的人脸',
          icon: 'fail'
        })
      }
    }
  }

  // 开始人脸检测
  const startFaceDetection = () => {
    setIsDetecting(true)
    const detect = () => {
      if (isDetecting) {
        detectFaces()
        requestAnimationFrame(detect)
      }
    }
    detect()
  }

  // 停止检测
  const stopDetection = () => {
    setIsDetecting(false)
    if (stream) {
      stream.getTracks().forEach(track => track.stop())
    }
    setStream(null)
    setDetectedFaces([])
    setMatchedFace(null)
  }

  // 开始验证
  const startVerification = async () => {
    if (faceDatabase.length === 0) {
      Toast.show({
        content: '请先注册人脸数据',
        icon: 'fail'
      })
      return
    }

    try {
      setIsLoading(true)
      setIsVerifying(true)
      setVerificationResult(null)
      
      const mediaStream = await navigator.mediaDevices.getUserMedia({
        video: {
          width: 640,
          height: 480,
          facingMode: 'user'
        }
      })
      
      setStream(mediaStream)
      
      if (videoRef.current) {
        videoRef.current.srcObject = mediaStream
        videoRef.current.play()
      }
      
      startFaceDetection()
      
      Toast.show({
        content: '开始人脸验证，请将面部对准摄像头',
        icon: 'success'
      })
    } catch (error) {
      console.error('验证启动失败:', error)
      Toast.show({
        content: '无法访问摄像头，请检查权限设置',
        icon: 'fail'
      })
      setIsVerifying(false)
    } finally {
      setIsLoading(false)
    }
  }

  // 停止验证
  const stopVerification = () => {
    setIsVerifying(false)
    setIsDetecting(false)
    if (stream) {
      stream.getTracks().forEach(track => track.stop())
    }
    setStream(null)
    setDetectedFaces([])
    setMatchedFace(null)
    setVerificationResult(null)
  }

  // 注册人脸
  const registerFace = () => {
    if (detectedFaces.length === 0) {
      Toast.show({
        content: '请先检测到人脸',
        icon: 'fail'
      })
      return
    }
    
    if (!registerName.trim()) {
      Toast.show({
        content: '请输入姓名',
        icon: 'fail'
      })
      return
    }
    
    const newFace: FaceFeature = {
      id: `face_${Date.now()}`,
      name: registerName.trim(),
      landmarks: detectedFaces[0].landmarks,
      descriptor: detectedFaces[0].descriptor,
      timestamp: Date.now()
    }
    
    const updatedDatabase = [...faceDatabase, newFace]
    saveFaceDatabase(updatedDatabase)
    
    Toast.show({
      content: '人脸注册成功！',
      icon: 'success'
    })
    
    setShowRegisterDialog(false)
    setRegisterName('')
  }

  // 清除人脸数据库
  const clearFaceDatabase = () => {
    Dialog.confirm({
      content: '确定要清除所有人脸数据吗？',
      onConfirm: () => {
        saveFaceDatabase([])
        Toast.show({
          content: '人脸数据库已清除',
          icon: 'success'
        })
      }
    })
  }

  // 组件卸载时清理
  useEffect(() => {
    return () => {
      if (stream) {
        stream.getTracks().forEach(track => track.stop())
      }
    }
  }, [stream])

  return (
    <div className={styles.page}>
      <Nabar title='人脸识别系统' sticky={false} />
      
      <div className={styles.content}>
        {/* 系统状态 */}
        <div className={styles.statusCard}>
          <div className={styles.statusTitle}>系统状态</div>
          <div className={styles.statusInfo}>
            <div className={styles.statusItem}>
              <span>检测状态:</span>
              <span className={isDetecting ? styles.active : styles.inactive}>
                {isDetecting ? (isVerifying ? '验证中' : '运行中') : '已停止'}
              </span>
            </div>
            <div className={styles.statusItem}>
              <span>人脸数据库:</span>
              <span>{faceDatabase.length} 条记录</span>
            </div>
            <div className={styles.statusItem}>
              <span>检测到人脸:</span>
              <span>{detectedFaces.length} 个</span>
            </div>
            {matchedFace && (
              <div className={styles.statusItem}>
                <span>匹配结果:</span>
                <span className={styles.matched}>{matchedFace.name}</span>
              </div>
            )}
            {verificationResult && (
              <div className={styles.statusItem}>
                <span>验证结果:</span>
                <span className={verificationResult === 'success' ? styles.success : styles.failed}>
                  {verificationResult === 'success' ? '验证成功' : '验证失败'}
                </span>
              </div>
            )}
          </div>
        </div>

        {/* 摄像头区域 */}
        <div className={styles.cameraContainer}>
          <div className={styles.videoWrapper}>
            <video
              ref={videoRef}
              className={styles.video}
              autoPlay
              muted
              playsInline
            />
            <canvas
              ref={canvasRef}
              className={styles.canvas}
            />
          </div>
        </div>

        {/* 操作按钮 */}
        <div className={styles.buttonContainer}>
          {!isDetecting ? (
            <div className={styles.buttonGroup}>
              <Button
                color='primary'
                size='large'
                onClick={startVerification}
                disabled={isLoading || faceDatabase.length === 0}
                className={styles.verifyBtn}
              >
                {isLoading ? '启动中...' : '开始验证'}
              </Button>
              <Button
                color='default'
                size='large'
                onClick={startCamera}
                disabled={isLoading}
                className={styles.startBtn}
              >
                {isLoading ? '启动中...' : '开始检测'}
              </Button>
              <Button
                color='success'
                size='large'
                onClick={() => setShowRegisterDialog(true)}
                className={styles.registerBtn}
              >
                注册人脸
              </Button>
            </div>
          ) : (
            <div className={styles.buttonGroup}>
              {!isVerifying ? (
                <>
                  <Button
                    color='success'
                    size='large'
                    onClick={() => setShowRegisterDialog(true)}
                    disabled={detectedFaces.length === 0}
                    className={styles.registerBtn}
                  >
                    注册当前人脸
                  </Button>
                  <Button
                    color='danger'
                    size='large'
                    onClick={stopDetection}
                    className={styles.stopBtn}
                  >
                    停止检测
                  </Button>
                </>
              ) : (
                <Button
                  color='danger'
                  size='large'
                  onClick={stopVerification}
                  className={styles.stopBtn}
                >
                  停止验证
                </Button>
              )}
            </div>
          )}
        </div>

        {/* 数据库管理 */}
        <div className={styles.databaseCard}>
          <div className={styles.databaseTitle}>人脸数据库管理</div>
          <div className={styles.databaseList}>
            {faceDatabase.map(face => (
              <div key={face.id} className={styles.databaseItem}>
                <UserOutline className={styles.userIcon} />
                <div className={styles.faceInfo}>
                  <div className={styles.faceName}>{face.name}</div>
                  <div className={styles.faceTime}>
                    {new Date(face.timestamp).toLocaleString()}
                  </div>
                </div>
              </div>
            ))}
            {faceDatabase.length === 0 && (
              <div className={styles.emptyDatabase}>暂无注册人脸</div>
            )}
          </div>
          <Button
            color='danger'
            size='small'
            onClick={clearFaceDatabase}
            disabled={faceDatabase.length === 0}
            className={styles.clearBtn}
          >
            清除数据库
          </Button>
        </div>
      </div>

      {/* 注册对话框 */}
      <Dialog
        visible={showRegisterDialog}
        onClose={() => setShowRegisterDialog(false)}
        content={
          <div className={styles.registerDialog}>
            <div className={styles.dialogTitle}>注册人脸</div>
            <Input
              placeholder="请输入姓名"
              value={registerName}
              onChange={setRegisterName}
              className={styles.nameInput}
            />
            <div className={styles.dialogButtons}>
              <Button
                color='default'
                onClick={() => setShowRegisterDialog(false)}
              >
                取消
              </Button>
              <Button
                color='primary'
                onClick={registerFace}
                disabled={!registerName.trim() || detectedFaces.length === 0}
              >
                注册
              </Button>
            </div>
          </div>
        }
      />
    </div>
  )
}

export default ProfessionalFaceRecognition
